package vista;

import interfaces.ILaberinto;
import interfaces.IVista;

import java.io.File;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import laberinto.Casilla;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import xml.xmlUtilidades;

public class VisualizacionXMLDeLaberinto implements IVista {

	private ILaberinto laberinto;
	private String rutaArchivoDestino;

	/**
	 * 
	 * @param laberinto modelo a ser invocado por la vista
	 * @param rutaArchivoDestino
	 */
	public VisualizacionXMLDeLaberinto(ILaberinto laberinto,String rutaArchivoDestino){
		this.laberinto = laberinto;
		this.rutaArchivoDestino = rutaArchivoDestino;
	}

	@Override
	public void actualizar(int iteracion) {
		exportarLaberinto(rutaArchivoDestino, laberinto,iteracion);
		
	}	
	
	private void exportarLaberinto(String rutaArchivoDestino, ILaberinto laberinto, int tickActual) {
		rutaArchivoDestino = xmlUtilidades.completarRuta(rutaArchivoDestino);
		rutaArchivoDestino = xmlUtilidades.completarNombreDeArchivo(rutaArchivoDestino, tickActual);
		try {

			DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder docBuilder = docFactory.newDocumentBuilder();

			Document xmlLaberintoActual = docBuilder.newDocument();
			Element nodoRaiz = xmlLaberintoActual.createElement("laberinto");
			xmlLaberintoActual.appendChild(nodoRaiz);
			
			nodoRaiz.setAttribute("ancho", Integer.toString(laberinto.obtenerCantidadColumnas()));
			nodoRaiz.setAttribute("alto", Integer.toString(laberinto.obtenerCantidadFilas()));
			nodoRaiz.setAttribute("inicioPacman", laberinto.obtenerCasillaInicialPacman().obtenerIdCasilla());
			nodoRaiz.setAttribute("inicioFantasmas", laberinto.obtenerCasillaInicialFantasmas().obtenerIdCasilla());

			grabarCasillas(xmlLaberintoActual, nodoRaiz, laberinto);
			
			// Escribe el documento xml en un nuevo archivo
			TransformerFactory transformerFactory = TransformerFactory.newInstance();
			Transformer transformer = transformerFactory.newTransformer();
			
			transformer.setOutputProperty(OutputKeys.INDENT, "yes");
			transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");

			DOMSource source = new DOMSource(xmlLaberintoActual);
			StreamResult result = new StreamResult(new File(rutaArchivoDestino));

			transformer.transform(source, result);

		} catch (ParserConfigurationException pce) {
			pce.printStackTrace();
		} catch (TransformerException tfe) {
			tfe.printStackTrace();
		}
	}
	
	private String convertirFilaColumnaEnId(int fila, int Columna){
		
		String idCasilla = String.format("%02d", fila);
		return idCasilla + String.format("%02d", Columna);
	}
	
	private void grabarCasillas(Document doc, Element nodoRaiz, ILaberinto laberinto) {
		
        //for (String idCasilla : laberinto.getLaberinto().keySet()) {
		//Lo que esta cometado es otra forma de recorrer todas las casillas pero sin orden
		//En caso de necesitarlo, descomentar y sacar las siguientes 3 lineas (y sacar una llave del for)
		String idCasilla;
		for (int filaActual = 0; filaActual <= laberinto.obtenerCantidadFilas()-1; filaActual++){
			for (int columnaActual = 0; columnaActual <= laberinto.obtenerCantidadColumnas()-1; columnaActual++){
            
				Element elementoCasilla = doc.createElement("nodo");
				nodoRaiz.appendChild(elementoCasilla);
				
				idCasilla = convertirFilaColumnaEnId(filaActual, columnaActual);
				
				Casilla casillAAGrabar = laberinto.obtenerCasillaPorId(idCasilla);
				
				elementoCasilla.setAttribute("id", idCasilla);
				elementoCasilla.setAttribute("fila", String.format("%02d", casillAAGrabar.obtenerFila()));
				elementoCasilla.setAttribute("columna", String.format("%02d",casillAAGrabar.obtenerColumna()));
	
				elementoCasilla.setAttribute("contiene", casillAAGrabar.obtenerBolitaBolon());
				
				if (casillAAGrabar.obtenerIzquierda() != null){
					elementoCasilla.setAttribute("izquierda", casillAAGrabar.obtenerIzquierda().obtenerIdCasilla());
				}else{
					elementoCasilla.setAttribute("izquierda", "");
				}
				
				if (casillAAGrabar.obtenerDerecha() != null){
					elementoCasilla.setAttribute("derecha", casillAAGrabar.obtenerDerecha().obtenerIdCasilla());			
				}else{
					elementoCasilla.setAttribute("derecha", "");
				}
				
				if (casillAAGrabar.obtenerArriba() != null){
					elementoCasilla.setAttribute("arriba", casillAAGrabar.obtenerArriba().obtenerIdCasilla());
				}else{
					elementoCasilla.setAttribute("arriba", "");
				}
				
				if (casillAAGrabar.obtenerAbajo() != null){
					elementoCasilla.setAttribute("abajo", casillAAGrabar.obtenerAbajo().obtenerIdCasilla());
				}else{
					elementoCasilla.setAttribute("abajo", "");
				}
			}
		}

	}
		
}
